﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="MainWindow.xaml.cs" company="dimamartovoi">
//   Apache License
//   Version 2.0, January 2004
//   http://www.apache.org/licenses
// </copyright>
// <summary>
//   Interaction logic for MainWindow.xaml
// </summary>
// --------------------------------------------------------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;

using ActorModel.Evolution;
using ActorModel.Infrastructure;
using ActorModel.Infrastructure.Configuration.Ivashenko;

using Common.Logging;

using Microsoft.Win32;

namespace SimpleUI
{
    public partial class MainWindow : Window
    {
        private readonly ILog log = LogManager.GetLogger("output");

        private int evolutionsCount;

        private IEngineFlowController<string> flowController;

        public MainWindow()
        {
            this.InitializeComponent();
        }

        private void OnEvolute(object sender, RoutedEventArgs e)
        {
            var evolutionTask = new Task(param =>
                {
                    var evolParams = (object[])param;
                    var count = (int) evolParams[0];
                    var controller = (IEngineFlowController<string>) evolParams[1];
                    var logger = (ILog) evolParams[2];

                    var stopWatch = Stopwatch.StartNew();
                    for (int i = 0; i < count; i++)
                    {
                        this.Dispatcher.Invoke(new Action<int, int>((i1, i2) => this.StatusLabel.Text = string.Format("Evolution {0}/{1}", i1, i2)), i + 1, count);
                        logger.TraceFormat("-----------------Evolution ({0})------------", evolParams);
                        controller.Evolute();
                        logger.Trace(this.flowController);
                    }

                    stopWatch.Stop();
                    this.Dispatcher.Invoke(
                        new Action<TimeSpan, int>(
                            (span, i) =>
                            this.StatusLabel.Text = string.Format("Elapsed {0} for {1} iterations.", span, i)),
                        new object[] {stopWatch.Elapsed, count});
                }, new object[] { this.EvolutionsCounter.Value.Value, this.flowController, this.log });
            evolutionTask.Start();
            
            
        }

        private void OnLoad(object sender, RoutedEventArgs e)
        {
            this.StatusLabel.Text = "Initializing...";

            try
            {
                var open = new OpenFileDialog
                {
                    DefaultExt = "*.evol",
                    Filter = "Evolution code file (.evol) | *.evol",
                    FileName = "life"
                };
                if (open.ShowDialog() == true)
                {
                    using (Stream stream = open.OpenFile())
                    {
                        using (var textStream = new StreamReader(stream))
                        {
                            var initTask = new Task<IEngineFlowController<string>>(state =>
                            {
                                var loader = new IvashenkoConfigLoader();
                                EngineStartParameters<string> parameters = loader.Load((string)state);
                                var engineBootstrapper = new EngineBootstrapper<string>(parameters);
                                return engineBootstrapper.Initialize();
                            }, textStream.ReadToEnd());
                            initTask.ContinueWith(task =>
                                {
                                    this.Dispatcher.Invoke(new Action<IEngineFlowController<string>>(controller =>
                                        {
                                            this.StatusLabel.Text = "Initialized";
                                            this.flowController = controller;
                                            this.log.Trace(controller);
                                        }), task.Result);
                                });
                            initTask.Start();
                        }
                       
                    }
                }
            }
            catch (Exception exception)
            {
                this.log.Error(exception);
            }
        }

        private void OnSetHandler(object sender, RoutedEventArgs e)
        {
            try
            {
                var open = new OpenFileDialog
                               {
                                   DefaultExt = "*.evol", 
                                   Filter = "Evolution code file (.evol) | *.evol", 
                                   FileName = "init"
                               };
                if (open.ShowDialog() == true)
                {
                    using (Stream stream = open.OpenFile())
                    {
                        using (var textStream = new StreamReader(stream))
                        {
                            var interpreter = new Interpreter();
                            Func<string, IEnumerable<string>, IEnumerable<string>> evolutionFunc =
                                interpreter.Interprete(textStream.ReadToEnd());
                            this.flowController.SetEvolutionHandler(evolutionFunc);
                        }
                    }
                }
            }
            catch (Exception exception)
            {
                MessageBox.Show(exception.ToString());
            }
        }
    }
}